﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;
using System.Data;
using System.Collections;
using FooFun.DataElements.Dtos;
using PhysicalDataProvider;
using DTOFrameworks;
using FooFun.Web.Utils;
using FooFun.Faq.Dal.Services;
using AccessGrant.GrantFrameworks;

namespace FAQFrameworks
{
    public class ForumManager
    {
        ForumService forumService;

        RecommendIndexService recommendService;

        DEDataProvider dataProvider;

        public ForumManager()
        {
            dataProvider = new DEDataProvider();

            forumService = new ForumService();
            recommendService = new RecommendIndexService();

            forumService.DataProvider = dataProvider;

            recommendService.DataProvider = dataProvider;

        }

        public void InitAllForumsFromDB()
        {
            dataProvider.Begin();

            IDataElement forums = forumService.SelectAllElement();

            dataProvider.End();

            foreach (IDataElement forumDE in forums)
            {
                CacheManager.Init[GetKey(forumDE["ForumId"])]
                    = new ForumDataElement(forumDE, forums);
            }
        }

        string GetKey(object forumId)
        {
            return "Forum_" + forumId;
        }

        public IDataElement GetElement(IDataElement forumId)
        {
            if (!forumId.Equals(Guid.Empty))
            {
                if (CacheManager.Init[GetKey(forumId)] == null)
                {
                    InitAllForumsFromDB();
                }

                IDataElement forumDE
                        = CacheManager.Init[GetKey(forumId)]
                        as IDataElement;

                if (forumDE != null)
                {
                    return forumDE;
                }
            }

            return new EmptyDataElement();
        }

        public IDataElement GetElement(Guid forumId)
        {
            if (CacheManager.Init[GetKey(forumId)] == null)
            {
                InitAllForumsFromDB();
            }

            IDataElement forumDE
                        = CacheManager.Init[
                        GetKey(SiteUrlsProvider.GetGuidBase64(forumId))
                        ]
                        as IDataElement;

            if (forumDE != null)
            {
                return forumDE;
            }

            return new EmptyDataElement();
        }

        public string GetTheme(Guid forumId)
        {
            string theme = null;
            IDataElement thisForum = GetElement(forumId);
            IDataElement de = thisForum;

            while (de != null && !de.IsEmpty)
            {
                theme = de["Theme"].Value as string;

                if (!string.IsNullOrEmpty(theme))
                {
                    thisForum["Theme"] = de["Theme"];
                    return theme;
                }

                de = de.Parent;
            }

            return theme;
        }

        public void FixTopic(Guid topicId)
        {
            TopicManager topicManager = new TopicManager();
            IDataElement topic = topicManager.GetElement(topicId);

            Guid forumId = DataProviderUtil.GetGuid(
                topic["@ForumId"].Value);

            dataProvider.Begin();

            recommendService.FixTopic(forumId, topicId);

            dataProvider.End();
        }

        public void EditNote(Guid guid, string p)
        {
            dataProvider.Begin();

            forumService.EditNote(guid, p);

            dataProvider.End();
        }

        public class ForumDataElement : CustomDataElement, IEnumItem
        {
            IDataElement forums;

            public ForumDataElement(IDataElement de, IDataElement forums)
                : base(de)
            {
                this.forums = forums;
            }

            public override IDataElement this[string attrName]
            {
                get
                {
                    switch (attrName)
                    {
                        case "Theme":
                            IDataElement de = InnerDataElement;

                            while (de["Theme"].IsEmpty)
                            {
                                de = de.Parent;
                            }

                            InnerDataElement["Theme"] = de["Theme"];
                            break;
                        default:
                            break;
                    }

                    return base[attrName];
                }
                set
                {
                    base[attrName] = value;
                }
            }

            public override IEnumerator GetEnumerator()
            {
                foreach (IDataElement f in forums)
                {
                    if (f["ParentId"].Equals(this["ForumId"]))
                    {
                        ForumDataElement forum
                            = new ForumDataElement(f, forums);
                        yield return forum;
                    }
                }
            }

            public override IDataElement Parent
            {
                get
                {
                    if (this.InnerDataElement["ForumId"].
                        Equals(base["ParentId"]))
                    {
                        return new EmptyDataElement("根板块");
                    }

                    ForumManager manager = new ForumManager();
                    IDataElement de
                        = manager.GetElement(base["ParentId"]);

                    return de;
                }
                set
                {
                    base.Parent = value;
                }
            }

            #region IEnumItem 成员

            public string Name
            {
                get
                {
                    return Convert.ToString(
                    this["ForumName"].Value);
                }
            }

            public Guid Id
            {
                get
                {
                    return DataProviderUtil.GetGuid(
                        this["ForumId"].Value);

                }
            }

            #endregion
        }
    }

}
